<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>SQL编辑器</title>
  <link rel="stylesheet" href="MonacoEditor/all.min.css">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css">
  <script src="MonacoEditor/min/vs/loader.js"></script>
  <style>
     * {
       margin: 0;
       padding: 0;
       box-sizing: border-box;
       font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
       font-family: 'Microsoft YaHei UI', 'Microsoft YaHei', '微软雅黑', sans-serif;
     }
     
     html, body {
       height: 100%;
       margin: 0;
       padding: 0;
       overflow: hidden; /* 防止出现滚动条 */
     }
      
     body {
       background-color: #f5f5f5;
       color: #333;
     }
     
     .container {
       width: 100%;
       height: 100vh;
       margin: 0;
       padding: 0;
       display: flex;
       flex-direction: column;
       overflow: hidden; /* 防止页面整体滚动 */
     }
     
     header {
       display: flex;
       justify-content: space-between;
       align-items: center;
       margin-bottom: 20px;
       padding-bottom: 10px;
       border-bottom: 1px solid #e0e0e0;
     }
     
     h1 {
       font-size: 24px;
       font-weight: 600;
       color: #2d3748;
     }
     
     .editor-container {
       border-radius: 12px;
       box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
       overflow: hidden;
       background-color: #fff;
       flex: 1;
       display: flex;
       flex-direction: column;
       position: relative;
       margin: 0;
       padding: 0;
     }
     
     /* 加载状态样式 */
     .loading-overlay {
       position: absolute;
       top: 0;
       left: 0;
       right: 0;
       bottom: 0;
       background-color: rgba(255, 255, 255, 0.9);
       display: flex;
       flex-direction: column;
       justify-content: center;
       align-items: center;
       z-index: 100;
       transition: opacity 0.3s ease;
     }
     
     .loading-spinner {
       width: 50px;
       height: 50px;
       border: 5px solid #f3f3f3;
       border-top: 5px solid #3b82f6;
       border-radius: 50%;
       animation: spin 1s linear infinite;
       margin-bottom: 16px;
     }
     
     @keyframes spin {
       0% { transform: rotate(0deg); }
       100% { transform: rotate(360deg); }
     }
     
     .loading-text {
       font-size: 16px;
       color: #4b5563;
       font-weight: 500;
     }
     
     #editor {
       width: 100%;
       height: 100%; /* 完全填充父容器高度 */
       transition: background-color 0.3s ease;
     }
     
     #editor.read-only {
       background-color: #f9f9f9;
     }
     
     .status-bar {
       padding: 8px 20px;
       background-color: #f8fafc;
       border-top: 1px solid #e2e8f0;
       font-size: 12px;
       color: #64748b;
       display: flex;
       justify-content: space-between;
     }
     
     .features-info {
       margin-top: 20px;
       padding: 16px;
       background-color: #eff6ff;
       border-radius: 8px;
       border-left: 4px solid #3b82f6;
     }
     
     .features-info h3 {
       font-size: 16px;
       color: #1e40af;
       margin-bottom: 8px;
       display: flex;
       align-items: center;
       gap: 8px;
     }
     
     .features-info ul {
       padding-left: 24px;
       font-size: 14px;
       color: #3b82f6;
     }
     
     .features-info li {
       margin-bottom: 4px;
     }
   </style>
</head>
<body>
  <div class="container">
    <div class="editor-container">
      <!-- 只读状态指示器 - 显示当前编辑器是只读还是编辑模式 -->
      <div style="position: absolute; top: 10px; right: 10px; z-index: 20;">
        <div id="read-only-indicator" style="display: flex; align-items: center; gap: 8px; 
            padding: 4px 12px; border-radius: 16px; font-size: 12px; 
            background-color: #f3f4f6; color: #374151;">
          <i class="fa-solid fa-lock" style="font-size: 12px;"></i>
          <span>只读模式</span>
        </div>
      </div>
      
      <div id="editor"></div>
      
      <!-- 功能提示区域 -->
      <div class="features-info" style="position: absolute; bottom: 20px; right: 20px; max-width: 300px; z-index: 10; margin-bottom: 20px; max-height: 200px; overflow-y: auto;">
        <h3>
          <span><i class="fa-solid fa-lightbulb"></i> 自动补全提示</span>
          <button onclick="this.closest('.features-info').style.display='none'" class="ml-2 text-gray-500 hover:text-gray-700 transition-colors" style="background:none;border:none;cursor:pointer;font-size:14px;">
            <i class="fa-solid fa-times"></i>
          </button>
        </h3>
        <ul>
          <li>输入SQL关键字时自动触发</li>
          <li>输入"."、"("、","等符号时触发</li>
          <li>使用Ctrl+Space手动触发</li>
        </ul>
      </div>
    </div>
  </div>
  <script>
        // 封装函数：获取当前网页的网络目录路径（不包含最后的HTML文件名）
        function getCurrentNetworkDirectoryPath() {
            var pathname = window.location.pathname;
            var lastSlashIndex = pathname.lastIndexOf('/');

            var directoryPath;
            if (lastSlashIndex > 0) {
                directoryPath = pathname.substring(0, lastSlashIndex + 1); // 保留最后的斜杠
            } else {
                directoryPath = '/'; // 根目录情况
            }

            var baseUrl = window.location.protocol + '//' + window.location.host + directoryPath;
            return baseUrl;
        }  
  </script>
  <script>
     //获取vs路径
    var vs_path = getCurrentNetworkDirectoryPath()+"MonacoEditor/min/vs";
    // 加载Monaco Editor编辑器
    require.config({ 
      paths: { 
        //'vs': 'MonacoEditor/min/vs',
		'vs': vs_path,
        // 注意：sql路径配置可能不需要，Monaco内置支持SQL
        //'sql': 'MonacoEditor/min/vs/language/sql'
      } 
    });
    
    require(['vs/editor/editor.main'], function() {
      // 初始化编辑器相关变量
      let isReadOnly = true; // 默认设置为只读模式
      
      // 脚本自动补全功能配置
      // 注册SQL语言的自动补全支持
      monaco.languages.registerCompletionItemProvider('sql', {
        provideCompletionItems: function(model, position) {
          // 获取当前行文本，用于上下文感知的自动补全
          const textUntilPosition = model.getValueInRange({
            startLineNumber: position.lineNumber,
            startColumn: 1,
            endLineNumber: position.lineNumber,
            endColumn: position.column
          });
          
          // SQL关键字列表
          const keywords = [
            'SELECT', 'FROM', 'WHERE', 'AND', 'OR', 'JOIN', 'ON', 'GROUP BY', 
            'ORDER BY', 'ASC', 'DESC', 'LIMIT', 'OFFSET', 'INSERT', 'INTO', 
            'VALUES', 'UPDATE', 'SET', 'DELETE', 'CREATE', 'TABLE', 'ALTER', 
            'DROP', 'ADD', 'COLUMN', 'PRIMARY KEY', 'FOREIGN KEY', 'NOT NULL',
            'NULL', 'DEFAULT', 'UNIQUE', 'INDEX', 'VIEW', 'AS', 'DISTINCT',
            'COUNT', 'SUM', 'AVG', 'MAX', 'MIN', 'HAVING', 'BETWEEN', 'LIKE'
          ];
          
          // SQL函数列表
          const functions = [
            'COUNT()', 'SUM()', 'AVG()', 'MAX()', 'MIN()', 'CONCAT()', 
            'SUBSTRING()', 'DATE()', 'NOW()', 'CAST()', 'COALESCE()'
          ];
          
          // 构建补全建议数组
          const suggestions = [];
          
          // 添加关键字补全建议
          keywords.forEach(keyword => {
            suggestions.push({
              label: keyword,
              kind: monaco.languages.CompletionItemKind.Keyword,
              insertText: keyword,
              insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
              documentation: keyword + ' SQL关键字'
            });
          });
          
          // 添加函数补全建议
          functions.forEach(func => {
            suggestions.push({
              label: func,
              kind: monaco.languages.CompletionItemKind.Function,
              insertText: func,
              insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
              documentation: func + ' SQL函数'
            });
          });
          
          return { suggestions: suggestions };
        }
      });
      
      // 创建Monaco编辑器实例
      const editor = monaco.editor.create(document.getElementById('editor'), {
        value: '', // 初始为空，将通过setSqlContent函数设置内容
        language: 'sql',  // 使用SQL语言模式
        theme: 'vs', // 使用浅色主题
        minimap: { enabled: true }, // 启用代码缩略图
        scrollBeyondLastLine: true, // 允许滚动超过最后一行
        fontSize: 12, // 字体大小
        wordWrap: 'on', // 自动换行
        lineNumbers: 'on', // 显示行号
        tabSize: 2, // 制表符大小
        automaticLayout: true, // 自动布局
        matchBrackets: 'always', // 总是匹配括号
        folding: true, // 启用代码折叠
        quickSuggestions: {
          other: true,        // 启用常规建议
          comments: false,    // 禁用注释中的建议
          strings: false      // 禁用字符串中的建议
        },
        suggest: {
          showWords: true,    // 显示单词建议
          showFunctions: true, // 显示函数建议
          showVariables: true, // 显示变量建议
          snippets: true      // 启用代码片段
        },
        parameterHints: {
          enabled: true       // 启用参数提示
        },
        suggestOnTriggerCharacters: true, // 启用触发字符建议
        colorDecorators: true,
        guides: {
          indentation: true,
          bracketPairs: true
        },
        readOnly: isReadOnly // 设置初始只读状态
      });
      
      // 将编辑器实例暴露到全局，以便外部JS访问
      window.sqlEditor = editor;
      
      /**
       * 设置SQL编辑器内容
       * @param {string} content - 要设置的SQL内容
       * @returns {Promise} - 返回一个Promise，表示操作完成
       */
      function setSqlContent(content) {
        return new Promise((resolve) => {
          if (window.sqlEditor) {
            window.sqlEditor.setValue(content);
            
            // 隐藏加载状态（如果存在）
            const loadingOverlay = document.querySelector('.loading-overlay');
            if (loadingOverlay) {
              loadingOverlay.style.opacity = "0";
              setTimeout(() => {
                loadingOverlay.style.display = "none";
                resolve(true);
              }, 300);
            } else {
              resolve(true);
            }
          } else {
            // 如果编辑器尚未加载完成，延迟重试
            setTimeout(() => {
              setSqlContent(content).then(resolve);
            }, 100);
          }
        });
      }
      
      /**
       * 获取当前编辑器中的SQL内容
       * @returns {string} - 编辑器中的SQL内容
       */
      function getSql() {
        if (window.sqlEditor) {
          return window.sqlEditor.getValue();
        }
        return '';
      }
      
      /**
       * 启用编辑模式（取消只读）
       */
      window.enableEditing = function() {
        isReadOnly = false;
        editor.updateOptions({ readOnly: isReadOnly });
        
        // 更新只读状态指示器
        const indicatorElement = document.getElementById('read-only-indicator');
        if (indicatorElement) {
          indicatorElement.innerHTML = '<i class="fa-solid fa-edit" style="font-size: 12px;"></i><span>编辑模式</span>';
          // 可以根据需要调整样式颜色
          indicatorElement.style.backgroundColor = '#eff6ff';
          indicatorElement.style.color = '#1e40af';
        }
      };
      
      /**
       * 禁用编辑模式（设置为只读）
       */
      window.disableEditing = function() {
        isReadOnly = true;
        editor.updateOptions({ readOnly: isReadOnly });
        
        // 更新只读状态指示器
        const indicatorElement = document.getElementById('read-only-indicator');
        if (indicatorElement) {
          indicatorElement.innerHTML = '<i class="fa-solid fa-lock" style="font-size: 12px;"></i><span>只读模式</span>';
          indicatorElement.style.backgroundColor = '#f3f4f6';
          indicatorElement.style.color = '#374151';
        }
      };
      
      /**
       * SQL加载完成后初始化相关逻辑
       */
      function initializeAfterSQLoaded() {
        console.log('SQL内容已加载，初始化相关JS逻辑');
        // 在这里可以添加需要在SQL加载完成后执行的其他逻辑
      }
    });
    
    /**
     * 全局函数：设置SQL内容
     * @param {string} content - SQL内容
     */
    function setSqlContent(content) {
      return new Promise((resolve) => {
        if (window.sqlEditor) {
          window.sqlEditor.setValue(content);
          
          // 隐藏加载状态，显示编辑器
          const loadingOverlay = document.querySelector('.loading-overlay');
          if (loadingOverlay) {
            loadingOverlay.style.opacity = "0";
            setTimeout(() => {
              loadingOverlay.style.display = "none";
              resolve(true);
            }, 300);
          } else {
            resolve(true);
          }
        } else {
          // 如果编辑器尚未加载完成，延迟重试
          setTimeout(() => {
            setSqlContent(content).then(resolve);
          }, 100);
        }
      });
    }
     
    /**
     * 全局函数：获取SQL内容
     * @returns {string} - 当前编辑器中的SQL内容
     */
    function getSql() {
      if (window.sqlEditor) {
        return window.sqlEditor.getValue();
      }
      return '';
    }
     
    /**
     * SQL加载完成后初始化JS逻辑的函数
     */
    function initializeAfterSQLoaded() {
      console.log('SQL内容已加载，初始化相关JS逻辑');
      // 在这里集中初始化所有依赖SQL内容的JS逻辑
    }

    // 活字格应用集成代码
    document.addEventListener('DOMContentLoaded', async function() {
      try {
        // 检查是否在活字格环境中
        if (window.parent && window.parent.Forguncy) {
          const Forguncy = window.parent.Forguncy;
          const $ = window.parent.$;
          
          // 从活字格单元格获取 SQL 脚本内容
          const sqlFromVariable = Forguncy.Page.getCell("vfgcScript").getValue();
          
          // 等待SQL内容加载完成后再初始化其他JS逻辑
          await setSqlContent(sqlFromVariable);
          
          // 根据需要设置初始模式（如果需要默认只读，可以调用disableEditing()）
          // disableEditing(); // 设置为只读模式
          // 或者启用编辑模式：enableEditing();
          
          // SQL加载完成后初始化所有相关JS逻辑
          initializeAfterSQLoaded();
        }
      } catch (error) {
        console.error('活字格集成代码执行错误:', error);
        // 即使发生错误，也尝试隐藏加载状态并初始化基础功能
        const loadingOverlay = document.querySelector('.loading-overlay');
        if (loadingOverlay) {
          loadingOverlay.style.opacity = "0";
          setTimeout(() => {
            loadingOverlay.style.display = "none";
          }, 300);
        }
      }
    });
  </script>
</body>
</html>
